package cn.sunxinao.pm.services;

import cn.sunxinao.pm.models.AbstractPet;
import cn.sunxinao.pm.utils.IReadWriteTool;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Scanner;

/**
 * 宠物管理抽象类
 */
public abstract class AbstractPetManager {
    /**
     * 宠物 id（创建时自动增加）
     */
    protected static long autoIncrement = 0;

    /**
     * 保存所有宠物
     */
    protected final List<AbstractPet> pets;

    /**
     * 数据持久化对象
     */
    protected final IReadWriteTool readWriteTool;

    /**
     * 要保存的文件路径
     */
    protected final File savePath;

    public AbstractPetManager(IReadWriteTool readWriteTool, File savePath) {
        this.savePath = savePath;
        if (!this.savePath.exists()) { // 创建文件
            try {
                if (!savePath.createNewFile())
                    System.err.println("提示: 无法创建文件，数据可能无法保存");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        this.readWriteTool = readWriteTool;
        this.pets = readWriteTool.readAllPets(savePath); // 读取文件
        for (AbstractPet pet : pets) {
            autoIncrement = Math.max(autoIncrement, pet.getId()); // 将自增值修改为当前最大的 Id
        }
    }

    /**
     * 创建一个空的宠物对象
     * （由子类创建）
     *
     * @return 一个空的宠物对象
     */
    public abstract AbstractPet createEmptyPet();

    /**
     * 根据键盘输入的信息添加宠物
     *
     * @param kb 标准输入对应的 Scanner
     * @return 是否成功
     */
    public boolean addPet(Scanner kb) {
        String tmpStr;
        float tmpFloat;
        AbstractPet pet = createEmptyPet();

        pet.setId(++autoIncrement);

        System.out.println("请输入宠物名字:");
        pet.setName(kb.nextLine().trim());

        do {
            System.out.println("请输入宠物性别[雌/雄]:");
            tmpStr = kb.nextLine();
        } while (!(tmpStr.equals("雌") || tmpStr.equals("雄")));
        pet.setSex(tmpStr.equals("雌"));

        do {
            System.out.println("请输入宠物年龄:");
            try {
                tmpFloat = Float.parseFloat(kb.nextLine().trim());
            } catch (NumberFormatException e) {
                System.err.println("请重试");
                tmpFloat = 0f;
            }
        } while (tmpFloat <= 0 || tmpFloat > 1000);
        pet.setAge(tmpFloat);

        System.out.println("请输入宠物类型[可空]:");
        pet.setType(kb.nextLine().trim());

        System.out.println("请输入宠物颜色[可空]:");
        pet.setColor(kb.nextLine().trim());

        do {
            System.out.println("请输入宠物入所时间[yyyy-MM-dd]:");
            tmpStr = kb.nextLine().trim();
        } while (!tmpStr.matches("^\\d{4}-(0?[1-9]|1[12])-(0?[1-9]|[12][0-9]|3[01])$"));
        pet.setJoinDate(tmpStr);

        System.out.println("请输入宠物主人[无人收养请留空]:");
        pet.setOwner(kb.nextLine().trim());
        pets.add(pet);
        System.out.println("添加成功\n");
        return true;
    }

    /**
     * 遍历数据并输出
     *
     * @return 是否有数据
     */
    public boolean list() {
        boolean success = false;
        for (AbstractPet pet : pets) {
            if (!success) {
                System.out.println("编号,\t名字,\t性别,\t年龄,\t类型,\t颜色,\t入所时间,\t领养人");
                success = true;
            }
            System.out.println(pet.display());
        }
        return success;
    }

    /**
     * 删除数据
     *
     * @param kb Scanner
     * @return 是否成功
     */
    public boolean delete(Scanner kb) {
        System.out.println("请输入宠物的id");
        long id;
        while (true) {
            try {
                id = Integer.parseInt(kb.nextLine().trim());
                if (id > 0) break;
            } catch (NumberFormatException ignored) {
                System.err.println("输入错误，请重试");
            }
        }
        boolean success = false;
        for (int i = 0; i < pets.size(); i++) {
            AbstractPet pet = pets.get(i);
            if (pet.getId() == id) {
                pets.remove(i);
                success = true;
                break; // 注意：在索引遍历中删除数据时，由于 List 为线性，必须更新索引的值以正确访问下一个数据，这里直接跳出
            }
        }
        return success;
    }

    /**
     * 查询数据
     *
     * @param kb Scanner
     * @return 是否成功
     */
    public boolean find(Scanner kb) {
        System.out.println("请输入宠物的id,名字,类型或者颜色");
        String str = kb.nextLine().trim();
        long id;
        try {
            id = Integer.parseInt(str);
        } catch (NumberFormatException ignored) {
            id = -1;
        }
        boolean success = false;
        for (AbstractPet pet : pets) {
            if (pet.getId() == id ||
                pet.getName().equals(str) ||
                pet.getType().contains(str) ||
                pet.getColor().contains(str)) {
                if (!success) System.out.println("编号,\t名字,\t,性别,\t年龄,\t类型,\t颜色,\t入所时间,\t领养人");
                System.out.println(pet.display());
                success = true;
            }
        }
        return success;
    }

    /**
     * 更新数据
     *
     * @param kb Scanner
     * @return 是否成功
     */
    public boolean update(Scanner kb) {
        System.out.println("请输入要修改的宠物的id");
        long id;
        while (true) {
            try {
                id = Integer.parseInt(kb.nextLine().trim());
                if (id > 0) break;
            } catch (NumberFormatException ignored) {
                System.err.println("输入错误，请重试");
            }
        }
        boolean success = false;
        for (AbstractPet pet : pets) {
            if (pet.getId() == id) {
                System.out.println("请输入新的信息，留空则不修改");
                String tmpStr;
                float tmpFloat;

                System.out.println("请输入宠物名字:");
                tmpStr = kb.nextLine().trim();
                if (tmpStr.isEmpty())
                    System.out.println("未更改");
                else
                    pet.setName(tmpStr);

                do {
                    System.out.println("请输入宠物性别[雌/雄]:");
                    tmpStr = kb.nextLine().trim();
                } while (!(tmpStr.isEmpty() || tmpStr.equals("雌") || tmpStr.equals("雄")));
                if (tmpStr.isEmpty())
                    System.out.println("未更改");
                else
                    pet.setSex(tmpStr.equals("雌"));

                do {
                    System.out.println("请输入宠物年龄:");
                    try {
                        tmpFloat = Float.parseFloat(kb.nextLine().trim());
                    } catch (NumberFormatException e) {
                        tmpFloat = 0f;
                    }
                } while (tmpFloat < 0 || tmpFloat > 1000);
                if (tmpFloat == 0)
                    System.out.println("未更改");
                else
                    pet.setAge(tmpFloat);

                System.out.println("请输入宠物类型");
                tmpStr = kb.nextLine().trim();
                if (tmpStr.isEmpty())
                    System.out.println("未更改");
                else
                    pet.setType(tmpStr);

                System.out.println("请输入宠物颜色:");
                tmpStr = kb.nextLine().trim();
                if (tmpStr.isEmpty())
                    System.out.println("未更改");
                else
                    pet.setColor(tmpStr);

                do {
                    System.out.println("请输入宠物入所时间[yyyy-MM-dd]:");
                    tmpStr = kb.nextLine().trim();
                } while (!(tmpStr.isEmpty() || tmpStr.matches("^\\d{4}-(0?[1-9]|1[12])-(0?[1-9]|[12][0-9]|3[01])$")));
                if (tmpStr.isEmpty())
                    System.out.println("未更改");
                else
                    pet.setJoinDate(tmpStr);

                System.out.println("请输入宠物主人[输入0删除]:");
                tmpStr = kb.nextLine().trim();
                if (tmpStr.isEmpty())
                    System.out.println("未更改");
                else
                    pet.setOwner(tmpStr.equals("0") ? "" : tmpStr);
                success = true;
                break;
            }
        }
        return success;
    }

    /**
     * 领养宠物
     *
     * @param kb Scanner
     * @return 是否成功
     */
    public boolean adopt(Scanner kb) {
        System.out.println("请输入宠物的id");
        long id;
        while (true) {
            try {
                id = Integer.parseInt(kb.nextLine().trim());
                if (id > 0) break;
            } catch (NumberFormatException ignored) {
                System.err.println("输入错误，请重试");
            }
        }
        boolean success = false;
        for (AbstractPet pet : pets) {
            if (pet.getId() == id) {
                System.out.println("请输入新的主人QaQ");
                pet.setOwner(kb.nextLine().trim());
                success = true;
                break;
            }
        }
        return success;
    }

    /**
     * 保存数据
     *
     * @return 是否成功
     */
    public boolean save() {
        return readWriteTool.saveAllPets(pets, savePath);
    }
}
